#include "front/text_normalize.h"

using namespace ppspeech;

const static vector<string> ones {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
const static vector<string> teens {"ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen","sixteen", "seventeen", "eighteen", "nineteen"};
const static vector<string> tens {"", "", "twenty", "thirty", "forty", "fifty", "sixty", "seventy", "eighty", "ninety"};
//123 -> one hundred twenty-three
string TextNormalizer::TnEn_Num2English(const long number)
{
	if (number < 10) {
		return ones[number];
	}
	else if (number < 20) {
		return teens[number - 10];
	}
	else if (number < 100) {
		return tens[number / 10] + ((number % 10 != 0) ? " " + TnEn_Num2English(number % 10) : "");
	}
	else if (number < 1000) {
		return TnEn_Num2English(number / 100) + " hundred" + ((number % 100 != 0) ? " " + TnEn_Num2English(number % 100) : "");
	}
	else if (number < 1000000L) {
		return TnEn_Num2English(number / 1000) + " thousand" + ((number % 1000 != 0) ? " " + TnEn_Num2English(number % 1000) : "");
	}
	else if (number < 1000000000L) {
		return TnEn_Num2English(number / 1000000L) + " million" + ((number % 1000000L != 0) ? " " + TnEn_Num2English(number % 1000000L) : "");
	}
	else if (number < 1000000000000L) {
		return TnEn_Num2English(number / 1000000000L) + " billion" + ((number % 1000000000L != 0) ? " " + TnEn_Num2English(number % 1000000000L) : "");
	}
	return " error ";
}

//序数词
const static vector<string> ordinal_ones {"","first", "second", "third", "fourth", "fifth", "sixth", "seventh", "eighth", "ninth"};
const static vector<string> ordinal_teens {"tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth","sixteenth", "seventeenth", "eighteenth", "nineteenth"};
const static vector<string> ordinal_tens {"", "", "twentieth", "thirtieth", "fortieth", "fiftieth", "sixtieth", "seventieth", "eightieth", "ninetieth"};
string TextNormalizer::TnEn_OrdinalNum2English(const long ordinal_number)
{
	if (ordinal_number < 10) {
		return ordinal_ones[ordinal_number];
	}
	else if (ordinal_number < 20) {
		return ordinal_teens [ordinal_number - 10];
	}
	else if (ordinal_number < 100) {
		return (ordinal_number % 10 == 0) ? (ordinal_tens[ordinal_number / 10]) : (tens[ordinal_number / 10] + " " + TnEn_OrdinalNum2English(ordinal_number % 10));
	}
	else if (ordinal_number < 1000) {
		return TnEn_Num2English(ordinal_number / 100) + " hundred" + ((ordinal_number % 100 != 0) ? " " + TnEn_OrdinalNum2English(ordinal_number % 100) : "th");
	}
	else if (ordinal_number < 1000000L) {
		return TnEn_Num2English(ordinal_number / 1000) + " thousand" + ((ordinal_number % 1000 != 0) ? " " + TnEn_OrdinalNum2English(ordinal_number % 1000) : "th");
	}
	else if (ordinal_number < 1000000000L) {
		return TnEn_Num2English(ordinal_number / 1000000L) + " million" + ((ordinal_number % 1000000L != 0) ? " " + TnEn_OrdinalNum2English(ordinal_number % 1000000L) : "th");
	}
	else if (ordinal_number < 1000000000000L) {
		return TnEn_Num2English(ordinal_number / 1000000000L) + " billion" + ((ordinal_number % 1000000000L != 0) ? " " + TnEn_OrdinalNum2English(ordinal_number % 1000000000L) : "th");
	}
	return " error ";
}

string TextNormalizer::TnEn_EachDigit2Str(const string& fcInputNumStr)
{
	string tResultStr = "";
	for(const char tChar : fcInputNumStr) {
		if(tChar >= '0' && tChar <= '9') {		//数字项
			tResultStr += ones.at( tChar-'0' );
		}
		else if(tChar >= 'a' && tChar <= 'z') {	//小写字母项
			tResultStr += char(tChar-0x20);
		}
		else {									//其他项
			tResultStr += tChar;
		}
		tResultStr += " ";
	}
	return tResultStr;
}


string TextNormalizer::TnEn_NumNegDec2Int(const string& fcInputNumStr)
{
	const bool tcInUseZero = false;
	if(fcInputNumStr.length() <= 0) {
		return "";
	}

	string tInputStr = fcInputNumStr;
	string tResultStr = " ";

	//-----------------
	if(tInputStr[0] == '-') {				//带负号
		tResultStr += " negative ";
		tInputStr = tInputStr.substr(1);	//去掉负号
	}
	else if(tInputStr[0] == '+') {			//带正号
		tResultStr += " positive ";
		tInputStr = tInputStr.substr(1);	//去掉正号
	}

	//-----------------
	vector<string> tItemDot = StrSplit(tInputStr, ".");
	//整数
	if(tItemDot[0].length() > 0) {
		tResultStr += TnEn_Num2English( stoi(tItemDot[0]) );
	}
	
	if(tItemDot.size() > 1) {	//带小数
		tResultStr += " point ";
		tResultStr += TnEn_EachDigit2Str( tItemDot[1] );
	}

	tResultStr += " ";
	return tResultStr;
}
